<?php declare(strict_types=1);

namespace App\Services\Vbill;

use App\Api\Controllers\Config\VbillConfigController;
use App\Exceptions\BizException;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class AuthenticationService
{

    public function weixin_config(\App\Api\Controllers\Vbill\BaseController $obj, $vbill_config, $mno, $subMchId, $subInfo)
    {
        //报备微信授权目录
        $url = $obj->weixin_config;
        $data = [
            'orgId' => $vbill_config->orgId,
            'reqId' => time(),
            'version' => '1.0',
            'timestamp' => date('Ymdhis', time()),
            'signType' => 'RSA',
            'reqData' => [
                'mno' => $mno,
                'subMchId' => $subMchId,
//                                'type'=>'jsapi',
                'type' => '03',
                'jsapiPath' => env('APP_URL') . '/api/vbill/weixin/'
            ],
        ];
//        dump($data);die;
        $result = $obj->execute($data, $url, $vbill_config->privateKey, $vbill_config->sxfpublic);
        $info = $result["data"];
        Log::channel("auth")->info("weixin_config", [
            "url" => $url,
            "req" => $data,
            "res" => $info
        ]);
        if (isset($info["respData"]["bizCode"]) && $info["respData"]["bizCode"] == "0000") {
            DB::table("vbill_sub_infos")->where("id", $subInfo->id)->update([
                "is_weixin_config" => 1
            ]);
        } else if (isset($info["respData"]["bizCode"]) && $info["respData"]["bizCode"] == "0001" && $info["respData"]["bizMsg"] == "支付授权目录已配置") {
            DB::table("vbill_sub_infos")->where("id", $subInfo->id)->update([
                "is_weixin_config" => 1
            ]);
        } else {
            DB::table("vbill_sub_infos")->where("id", $subInfo->id)->update([
                "weixin_config_reason" => json_encode($result["data"])
            ]);
        }
    }

    public function certification(string $store_id): array
    {
        $three = DB::table("vbill_three_qrcodes")->where("store_id", $store_id)->first();
        if (empty($three)) {
            DB::table("vbill_three_qrcodes")->insert([
                "store_id" => $store_id,
            ]);
        }
        $vbillStore = Db::table('vbill_stores')->where(['store_id' => $store_id])->first();
        if (empty($vbillStore)) {
            return [false, "未开通随行付通道"];
        }
        $config = new VbillConfigController();
        $vbill_config = $config->vbill_config($vbillStore->config_id);

        $obj = new \App\Api\Controllers\Vbill\BaseController();
        $subInfo = DB::table("vbill_sub_infos")->where("store_id", $vbillStore->store_id)->first();
        if (empty($subInfo) || empty($subInfo->weixin_mch_id) || empty($subInfo->alipay_mch_id)) {
            try {
                list($isOK, $subInfo) = (new IncomeResultService())->query($vbillStore->store_id);
                if ($isOK == false) {
                    return [false, "进件信息异常,请重新进件： <br/>" . $subInfo];
                }
            } catch (\Exception $e) {
                Log::channel("auth")->info("IncomeResultService", [
                    $e->getMessage(),
                    $e->getLine(),
                    $e->getFile()
                ]);
                return [false, "进件查询异常： <br/>" . $e->getMessage()];
            }

        }

        if (!empty($subInfo) && $subInfo->is_weixin_config == 0) {
            $this->weixin_config($obj, $vbill_config, $vbillStore->mno, $subInfo->weixin_mch_id, $subInfo);
        }
        $data = [
            'orgId' => $vbill_config->orgId,
            'reqId' => time(),
            'version' => '1.0',
            'timestamp' => date('Ymdhis', time()),
            'signType' => 'RSA',
            'reqData' => [
//                'applicationId' => $JdStoreItem[0]->applicationId, // f76c284da5644575aabe94043ccb637d
                'mno' => $vbillStore->mno,
                // 'contactName' => '童大伟',
                // 'phoneNumber' => '15601860037',
                // 'contactIdNo' => '342423199007116071',
            ],
        ];
        $wxAuth = $subInfo->wx_auth;
        $zfbAuth = $subInfo->zfb_auth;
        $wxAuthReason = $subInfo->wx_auth_reason;
        $zfbAuthReason = $subInfo->zfb_auth_reason;
        if (!in_array($wxAuth, [1, 2])) {
            //申请微信
            $url = $obj->wechat_commit_apply;
            $result = $obj->execute($data, $url, $vbill_config->privateKey, $vbill_config->sxfpublic);
            $info = $result["data"];
            Log::channel("auth")->info("certification_wx", [
                "url" => $url,
                "req" => $data,
                "res" => $result
            ]);
            if (isset($info['respData']) && $info['respData']['bizCode'] == '0000') {
                $wxAuth = 1;
            } else {
                $wxAuthReason = $info['respData']['bizMsg'] ?? "申请失败";
            }
        }
        //申请支付宝
        if (!in_array($zfbAuth, [1, 2])) {
            $url = $obj->alipay_commit_apply;
            $res = $obj->execute($data, $url, $vbill_config->privateKey, $vbill_config->sxfpublic);
            Log::channel("auth")->info("certification_ali", [
                "url" => $url,
                "req" => $data,
                "res" => $res
            ]);
            // dump($res);die;
            if ($res['data']['respData']['bizCode'] == '0000') {
                $zfbAuth = 1;
            } else {
                $zfbAuthReason = $res['data']['respData']['bizMsg'] ?? "申请失败";
            }
        }
        DB::table("vbill_sub_infos")->where("store_id", $vbillStore->store_id)->update([
            "wx_auth" => $wxAuth,
            "zfb_auth" => $zfbAuth,
            "wx_auth_reason" => $wxAuthReason,
            "zfb_auth_reason" => $zfbAuthReason
        ]);
        return [true, ""];
    }

    public function queryApplyInfo(string $store_id, bool $bool, string $msg): array
    {
        if ($bool == false) {
            return [
                "store_qr" => env("APP_URL") . '/qr?store_id=' . $store_id,
                "wx_auth" => -2,
                "zfb_auth" => -2,
                "wx_url" => "",
                "zfb_url" => "",
                "wx_auth_reason" => "【微信】" . $msg,
                "zfb_auth_reason" => "【支付宝】" . $msg,
                "weixin_mch_id" => "",
                "alipay_mch_id" => ""
            ];
        }
        $vbillStore = Db::table('vbill_stores')->where(['store_id' => $store_id])->first();
        if (empty($vbillStore)) {
            throw new BizException("随行付mno不存在");
        }
        $subInfo = DB::table("vbill_sub_infos")->where("store_id", $vbillStore->store_id)->first();
        if (empty($subInfo)) {
            throw new BizException("申请记录不存在");
        }
        $wxAuth = $subInfo->wx_auth;
        $zfbAuth = $subInfo->zfb_auth;
        $wxAuthQrcode = $subInfo->wx_url;
        $zfbAuthQrcode = $subInfo->zfb_url;
        $wxAuthReason = $subInfo->wx_auth_reason;
        $zfbAuthReason = $subInfo->zfb_auth_reason;
        $config = new VbillConfigController();
        $vbill_config = $config->vbill_config($vbillStore->config_id);
        $obj = new \App\Api\Controllers\Vbill\BaseController();

        $data = [
            'orgId' => $vbill_config->orgId,
            'reqId' => time(),
            'version' => '1.0',
            'timestamp' => date('Ymdhis', time()),
            'signType' => 'RSA',
            'reqData' => [
                'mno' => $vbillStore->mno,
            ],
        ];
        if ($wxAuth != 2 && !empty($subInfo->weixin_mch_id)) {
            $url = $obj->queryApplyInfo;
            $result = $obj->execute($data, $url, $vbill_config->privateKey, $vbill_config->sxfpublic);
            Log::channel("auth")->info("query-wx", [
                "url" => $url,
                "req" => $data,
                "res" => $result
            ]);
            //-2未开通随行付通道 -1 审核失败 0待审核 1 审核中 2 审核成功
            if ($result["data"]["code"] != "0000") {
                throw new BizException("微信认证码请求异常");
            }
            if ($result["data"]["respData"]["bizCode"] != "0000") {
                DB::table("vbill_sub_infos")->where("store_id", $vbillStore->store_id)->update([
                    "wx_auth" => 0,
                    "wx_url" => "",
                    "wx_auth_reason" => $result["data"]["respData"]["bizMsg"],
                ]);
                throw new BizException("请重新申请：" . $result["data"]["respData"]["bizMsg"] ?? "微信认证码请求异常");
            }
            //当申请单状态为待确认联系信息、待法人授权、审核通过、已冻结时，会返回小程序码图片链接地址
            if (in_array($result["data"]["respData"]["idenStatus"], [
                "APPLYMENT_STATE_WAITTING_FOR_CONFIRM_CONTACT",
                "APPLYMENT_STATE_WAITTING_FOR_CONFIRM_LEGALPERSON",
                "APPLYMENT_STATE_PASSED",
                "APPLYMENT_STATE_FREEZED",
            ])) {
                $wxAuth = 2;
                $wxAuthReason = "";
                $wxAuthQrcode = $this->upQr($result['data']["respData"]["infoQrcode"] ?? "");
            } elseif (in_array($result["data"]["respData"]["idenStatus"], [
                "APPLYMENT_STATE_WAITTING_FOR_AUDIT",
                "APPLYMENT_STATE_CANCELED"
            ])) {
                $wxAuth = 1;
                $wxAuthQrcode = "";
                $wxAuthReason = "原因：" . empty($result['data']['respData']['rejectInfo']) ? "微信审核中，请耐心等待" : $result['data']['respData']['rejectInfo'];
            } else if (in_array($result["data"]["respData"]["idenStatus"], [
                "APPLYMENT_STATE_OPENACCOUNT ",
            ])) {
                $wxAuth = -2;
                $wxAuthQrcode = "";
                $wxAuthReason = "原因：已开户";
            } else {
                $wxAuth = -1;
                $wxAuthQrcode = "";
                $wxAuthReason = "原因：" . ($result['data']['respData']['rejectInfo'] ?? "");
            }
        }
        if ($zfbAuth != 2 && !empty($subInfo->alipay_mch_id)) {
            $url = $obj->alipayQueryApplyInfo;
            $result = $obj->execute($data, $url, $vbill_config->privateKey, $vbill_config->sxfpublic);
            Log::channel("auth")->info("query-zfb", [
                "url" => $url,
                "req" => $data,
                "res" => $result
            ]);
            //-2未开通随行付通道 -1 审核失败 0待审核 1 审核中 2 审核成功
            if ($result["data"]["code"] != "0000") {
                throw new BizException("支付宝认证码请求异常");
            }
            if ($result["data"]["respData"]["bizCode"] != "0000") {
                DB::table("vbill_sub_infos")->where("store_id", $vbillStore->store_id)->update([
                    "zfb_auth" => 0,
                    "zfb_url" => "",
                    "zfb_auth_reason" => $result["data"]["respData"]["bizMsg"],
                ]);
                throw new BizException("请重新申请：" . $result["data"]["respData"]["bizMsg"] ?? "微信认证码请求异常");
            }
            //当申请单状态为待确认联系信息、待法人授权、审核通过、已冻结时，会返回小程序码图片链接地址
            if (in_array($result["data"]["respData"]["idenStatus"], [
                "CONTACT_CONFIRM",
                "LEGAL_CONFIRM",
                "AUDIT_PASS",
                "CONTACT_PROCESSING ",
                "AUDIT_FREEZE"
            ])) {
                $zfbAuth = 2;
                $zfbAuthReason = "";
                $fileName = $result['data']["respData"]["infoQrcode"] ?? "";
                $fileName = substr($fileName, strrpos($fileName, "/") + 1, strrpos($fileName, ".") - strrpos($fileName, "/") - 1);
                $zfbAuthQrcode = $this->upQr($result['data']["respData"]["infoQrcode"] ?? "", $fileName . ".jpg");
            } elseif (in_array($result["data"]["respData"]["idenStatus"], [
                "AUDITING",
                "CANCELED"
            ])) {
                $zfbAuth = 1;
                $zfbAuthQrcode = "";
                $zfbAuthReason = "原因：" . empty($result['data']['respData']['rejectInfo']) ? "支付宝审核中，请耐心等待" : $result['data']['respData']['rejectInfo'];
            } else {
                $zfbAuth = -1;
                $zfbAuthQrcode = "";
                $zfbAuthReason = "原因：" . ($result['data']['respData']['rejectInfo'] ?? "");
            }
        }
        DB::table("vbill_sub_infos")->where("store_id", $vbillStore->store_id)->update([
            "wx_auth" => $wxAuth,
            "zfb_auth" => $zfbAuth,
            "wx_url" => $wxAuthQrcode,
            "zfb_url" => $zfbAuthQrcode,
            "wx_auth_reason" => $wxAuthReason,
            "zfb_auth_reason" => $zfbAuthReason
        ]);

        return [
            "store_qr" => env("APP_URL") . '/qr?store_id=' . $store_id,
            "wx_auth" => $wxAuth,
            "zfb_auth" => $zfbAuth,
            "wx_url" => $wxAuthQrcode,
            "zfb_url" => $zfbAuthQrcode,
            "wx_auth_reason" => $wxAuthReason,
            "zfb_auth_reason" => $zfbAuthReason,
            "weixin_mch_id" => $subInfo->weixin_mch_id,
            "alipay_mch_id" => $subInfo->alipay_mch_id
        ];
    }


    public function upQr($file, $fileName = "")
    {
        if (empty($file)) {
            return "";
        }
        if (!is_dir(public_path() . "/threeCode/")) {
            mkdir(public_path() . "/threeCode/", 0755, true);
        }
        if (empty($fileName)) {
            $fileName = substr($file, strrpos($file, "/") + 1, strrpos($file, ".") - strrpos($file, "/") - 1);
            $file_path = "/threeCode/" . $fileName . rand(10000, 99999) . "." . substr($file, strrpos($file, ".") + 1); // 新文件名
        } else {
            $file_path = "/threeCode/" . uniqid() . $fileName;
        }
        file_put_contents(public_path() . $file_path, file_get_contents($file));
        $url = url($file_path);
        if (strpos($url, "https") === false) {
            $url = str_replace("http", "https", $url);
        }
        return $url;
    }

    public function backApplyBill(string $store_id)
    {
        $vbillStore = Db::table('vbill_stores')->where(['store_id' => $store_id])->first();
        if (empty($vbillStore)) {
            throw new BizException("随行付mno不存在");
        }
        $info = DB::table("vbill_sub_infos")->where("store_id", $vbillStore->store_id)->first();
        if (empty($info)) {
            throw new BizException("认证码记录不存在");
        }

        $config = new VbillConfigController();
        $vbill_config = $config->vbill_config($vbillStore->config_id);
        $obj = new \App\Api\Controllers\Vbill\BaseController();
        $data = [
            'orgId' => $vbill_config->orgId,
            'reqId' => time(),
            'version' => '1.0',
            'timestamp' => date('Ymdhis', time()),
            'signType' => 'RSA',
            'reqData' => [
                'mno' => $vbillStore->mno,
            ],
        ];
//            "wx_auth" => $wxAuth,
//            "zfb_auth" => $zfbAuth,
//            "wx_url" => $wxAuthQrcode,
//            "zfb_url" => $zfbAuthQrcode,
//            "wx_auth_reason" => $wxAuthReason,
//            "zfb_auth_reason" => $zfbAuthReason
        $wxAuth = $info->wx_auth;
        $zfbAuth = $info->zfb_auth;
        $wxAuthQrcode = $info->wx_url;
        $zfbAuthQrcode = $info->zfb_url;
        $wxAuthReason = $info->wx_auth_reason;
        $zfbAuthReason = $info->zfb_auth_reason;

        $reason = "";

        $url = $obj->backApplyBill;
        $res = $obj->execute($data, $url, $vbill_config->privateKey, $vbill_config->sxfpublic);
        Log::channel("auth")->info("backApplyBill-wx", [
            "url" => $url,
            "req" => $data,
            "res" => $res
        ]);
        if ($res['data']['respData']['bizCode'] == '0000') {
            $wxAuth = 0;
            $wxAuthReason = "";
            $wxAuthQrcode = "";
        } else {
            $reason .= $res['data']['respData']['bizMsg'] ?? "撤销失败";
        }
        $url = $obj->alipayBackApplyBill;
        $res = $obj->execute($data, $url, $vbill_config->privateKey, $vbill_config->sxfpublic);
        Log::channel("auth")->info("backApplyBill-zfb", [
            "url" => $url,
            "req" => $data,
            "res" => $res
        ]);
        if ($res['data']['respData']['bizCode'] == '0000') {
            $zfbAuth = 0;
            $zfbAuthReason = "";
            $zfbAuthQrcode = "";
        } else {
            $reason .= "" . ($res['data']['respData']['bizMsg'] ?? "撤销失败");
        }
        DB::table("vbill_sub_infos")->where("store_id", $vbillStore->store_id)->update([
            "wx_auth" => $wxAuth,
            "zfb_auth" => $zfbAuth,
            "wx_url" => $wxAuthQrcode,
            "zfb_url" => $zfbAuthQrcode,
            "wx_auth_reason" => $wxAuthReason,
            "zfb_auth_reason" => $zfbAuthReason
        ]);
        DB::table("vbill_three_qrcodes")->where("store_id", $vbillStore->store_id)->update([
            "wx_qr" => "",
            "zfb_qr" => ""
        ]);
        return [true, $reason];
    }

    public function mergeImage()
    {
        $bigImgPath = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" . $ret['ticket'];
        $qCodePath = "https://sxt-upyun.shengxiaotao.com/icons/96x96.png";
        $bigImg = imagecreatefromstring(file_get_contents($bigImgPath));
        $qCodeImg = imagecreatefromstring(file_get_contents($qCodePath));
        imagecopymerge($bigImg, $qCodeImg, 170, 170, 0, 0, 96, 96, 100);
        $path = ROOT_PATH . 'public/uploads/qc.png';
        imagejpeg($bigImg, $path);
    }

}